<template>
  <div class="include-all-select-wrapper">
    <a-select
      v-model="selectValue"
      v-model:popup-visible="popupVisible"
      placeholder="请选择"
      allow-search
      popup-container=".include-all-select-wrapper"
      multiple
      v-bind="$attrs"
      allow-clear
      @change="handleOptionChange"
    >
      <!-- options -->
      <a-option v-for="(item, optionIndex) in mergedOptions" :key="optionIndex" :value="item[valueProp]" :label="item[labelProp]">
        <slot name="option" :option="item" :index="optionIndex"></slot>
      </a-option>
    </a-select>
  </div>
</template>
<script setup name="includeAllSelect">
  import { ref, watch, computed } from 'vue'
  const props = defineProps({
    modelValue: Array,
    // 全部选中的文本
    checkAllText: {
      type: String,
      default: '全部',
    },
    // 是否默认选中全部
    defaultCheckAll: {
      type: Boolean,
      default: false,
    },
    // 列表数据项
    options: Array,
    labelProp: {
      type: String,
      default: 'label',
    },
    valueProp: {
      type: String,
      default: 'value',
    },
  })
  // emits
  const emit = defineEmits(['update:modelValue', 'change'])
  // popupVisible 控制下拉框的显示与隐藏
  const popupVisible = ref(false)
  // 选中的值
  const selectValue = ref([])
  // 记录是否选中全选
  const hasCheckedAll = ref(props.defaultCheckAll)

  // mergedOptions
  const mergedOptions = computed(() => {
    if (props.options?.length > 0) {
      const allValue = props.options.map((item) => item[props.valueProp])
      return [{ [props.labelProp]: props.checkAllText, [props.valueProp]: allValue }, ...props.options]
    } else {
      return []
    }
  })

  // 如果默认选中全部，则当 options 传值改变时，重新初始化计算 mergedValue
  if (props.defaultCheckAll) {
    watch(
      () => props.options,
      (newVal) => {
        if (newVal?.length > 0) {
          // 初始化 mergedValue
          const mergedValue = props.options.map((item) => item[props.valueProp])
          // 初始化 selectValue
          selectValue.value = [mergedOptions.value[0].value]
          emit('update:modelValue', mergedValue)
        }
      },
      { immediate: true }
    )
  }

  /**
   * 下拉框 change
   * @param {*} value
   */
  const handleOptionChange = (value) => {
    // 做全选和其他项不能同时选中处理
    if (hasCheckedAll.value) {
      if (value.length > 1) {
        selectValue.value = selectValue.value.filter((item) => !(typeof item == 'object'))
      }
    } else {
      if (selectValue.value.some((item) => typeof item == 'object')) {
        selectValue.value = selectValue.value.filter((item) => typeof item == 'object')
        if (selectValue.value.length == 1) {
          popupVisible.value = false
        }
      }
    }
    hasCheckedAll.value = selectValue.value.some((item) => typeof item == 'object')
    let selValue = selectValue.value
    if (hasCheckedAll.value) {
      selValue = selValue[0]
    }
    emit('update:modelValue', selValue)
    emit('change', selValue)
  }
</script>
<style lang="less" scoped>
  .include-all-select-wrapper {
    width: 100%;
    position: relative;
  }
</style>
